package main

import (
	"fmt"
	"golang.org/x/net/ipv4"
	"net"
)

// 自定义协议封装，
func main() {
	// 用于进行数据包的网卡的IP，一般是en0网卡吧
	serverIP := "143.198.107.33:17" // 10.17.100.123, ip任意.
	// 这种方式下无法连续接收同一个包的两次udp包.
	// 开启基于IP的udp协议报文监听(默认端口是17)
	//listener, error := net.ListenPacket("ip4:udp", serverIP) // ,IP transports, 自定义的ip协议：.
	//if error != nil {
	//	fmt.Println("开启监听错误" + error.Error())
	//	return
	//}
	listener, error := net.ListenPacket("udp4", serverIP) //:q ,IP transports, 自定义的ip协议：.
	if error != nil {
		fmt.Println("开启监听错误" + error.Error())
		return
	}
	defer listener.Close()

	// 把监听得到的报文传输到ipv的Conn，用来解析IP报文
	connection, err := ipv4.NewRawConn(listener)
	if err == nil {
		fmt.Println("创建Connection错误" + error.Error())
		return
	}
	defer connection.Close()

	// 开启无线循环获取报文
	for {
		buf := make([]byte, 2000)
		// 获取报文同时解析IP报文，得到IP头和IP头后面部分（传输层和应用层）
		hdr, payload, _, error := connection.ReadFrom(buf)
		if error != nil {
			fmt.Println("解析IP头错误" + error.Error())
			return
		}

		// 打印IP头
		fmt.Println("Head is:================\n ")
		fmt.Println(hdr)
		// 打印IP头后面的部分
		fmt.Println("Payload is:================\n ")
		fmt.Println(payload)
	}
}
